<template>
  <ul class="flip" ref="$ul" :style="filpCardStyle">
    <slot></slot>
  </ul>
</template>
<script setup>
import { ref, computed, nextTick } from "vue";

const props = defineProps({
  // 样式参数
  cardStyle: {
    type: Object,
    default: () => {
      return {
        width: 60, // 卡片宽度
        height: 90, // 卡片高度
        dividerHeight: 2, // 分割线高度
        perspective: 160, // 透视距离
        dividerColor: "rgba(0, 0, 0, 0.4)", // 分割线颜色
      };
    },
  },
});

/**
 * 样式参数
 */
const filpCardStyle = computed(() => {
  return {
    "--filp-card-width": props.cardStyle.width + "px",
    "--filp-card-height": props.cardStyle.height + "px",
    "--filp-card-divider-color": props.cardStyle.dividerColor,
    "--filp-card-divider-height": props.cardStyle.dividerHeight + "px",
    "--filp-card-perspective": props.cardStyle.perspective + "px",
  };
});

// 获取数字容器和所有数字li
const $ul = ref();

// 当前显示的数字索引（初始0）
let currentIndex = 0;

/**
 * 翻页函数，由程序自己控制翻页index
 */
function flip() {
  const $lis = Array.from($ul.value.children);

  // 1. 移除所有li的类（重置状态）
  $lis.forEach((li) => li.classList.remove("active", "before"));

  // 2. 旧数字添加before类（触发上半块翻转消失）
  $lis[currentIndex].classList.add("before");

  // 3. 更新索引（如果到最后一个，回到0）
  currentIndex = (currentIndex + 1) % $lis.length;

  // 4. 新数字添加active类（触发下半块翻转出现）
  $lis[currentIndex].classList.add("active");
}

/**
 * 翻页函数，由用户主动控制翻页index
 * @param beforeIndex 旧数字索引
 * @param nextIndex 新数字索引
 */
function flipByIndex(beforeIndex, nextIndex) {
  const $lis = Array.from($ul.value.children);

  // 1. 移除所有li的类（重置状态）
  $lis.forEach((li) => li.classList.remove("active", "before"));

  // 2. 旧数字添加before类（触发上半块翻转消失）
  $lis[beforeIndex].classList.add("before");

  // 3. 新数字添加active类（触发下半块翻转出现）
  $lis[nextIndex].classList.add("active");
}

defineExpose({
  flip,
  flipByIndex,
});
</script>
<style lang="scss">
.flip {
  font-family: Helvetica;
  position: relative;
  width: var(--filp-card-width);
  height: var(--filp-card-height);
  border-radius: 6px;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.7);
  perspective: var(--filp-card-perspective); /* 核心：给容器加透视，模拟人眼观察距离 */

  * {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  li {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    transform-style: preserve-3d; /* 核心：子元素继承3D空间 */
    z-index: 1; /* 所有都默认最低层级 */

    // 第一个元素默认第二层级
    &:nth-child(1) {
      z-index: 2;
    }

    .up {
      position: absolute;
      top: 0;
      width: 100%;
      height: 50%; /* 高度占一半 */
      overflow: hidden; /* 隐藏下半部分 */
      transform-origin: bottom center; /* 旋转原点：底部中间（向下扣） */
      border-radius: 6px 6px 0 0;
      background: var(--filp-card-background-color);

      // 添加一条分割线
      &::after {
        content: "";
        position: absolute;
        bottom: 0;
        left: 0;
        width: 100%;
        height: var(--filp-card-divider-height);
        background-color: var(--filp-card-divider-color);
      }

      /* 数字内容：上下半块的数字要错位显示 */
      .inn {
        position: absolute;
        top: 0;
        width: 100%;
        height: 200%; /* 高度200%，方便上下半块截取 */
      }
    }

    .down {
      position: absolute;
      bottom: 0;
      width: 100%;
      height: 50%;
      overflow: hidden; /* 隐藏上半部分 */
      transform-origin: top center; /* 旋转原点：顶部中间（向上翻） */
      border-radius: 0 0 6px 6px;

      // 添加一条分割线
      &::after {
        content: "";
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: var(--filp-card-divider-height);
        background-color: var(--filp-card-divider-color);
      }

      /* 下半块的数字：底部对齐（显示下半部分） */
      .inn {
        position: absolute;
        bottom: 0;
        width: 100%;
        height: 200%; /* 高度200%，方便上下半块截取 */
      }
    }
  }

  // li加上active类时的效果
  li.active {
    animation: asd 0.5s 0.5s linear both;

    // active状态的li的下半块动画
    .down {
      z-index: 2;
      animation: turn 0.5s 0.5s linear both;
    }
  }

  // li加上before时的效果
  li.before {
    z-index: 3;

    // before状态的li的上半块动画
    .up {
      z-index: 2;
      animation: turn2 0.5s linear both;
    }
  }
}

@keyframes asd {
  0% {
    z-index: 2;
  }

  10% {
    z-index: 4;
  }

  100% {
    z-index: 4;
  }
}

@keyframes turn {
  0% {
    transform: rotateX(90deg);
  }

  100% {
    transform: rotateX(0deg);
  }
}

@keyframes turn2 {
  0% {
    transform: rotateX(0deg);
  }

  100% {
    transform: rotateX(-90deg);
  }
}
</style>
